#ifndef DATABASE_H_
#define DATABASE_H_

#include "../lib/SharedMemory.h"
#include "../lib/Semaphore.h"

#include "../shared/DBRegister.h"

#include "../util/definitions.h"

#include "RegisterBlock.h"

#include <list>

/***
 *
 * Controla el acceso a la base de datos
 * siguiendo el modelo de lectores y escritores
 * con preferencia de lectores
 * mediante semaforos
 *
 */


class DataBase {

private:

	std::list< SharedMemory<RegisterBlock> > db;	/* lista de bloques de memoria compartida */

	Semaphore 	db_mutex;	/* controla el acceso concurrente a la base de datos */
	Semaphore	rc_mutex;	/* mutex sobre la variable readersCount */

	SharedMemory<int> 	readersCount;	/* cuenta la cantidad de lectores */


private:

	void readLock();
	void readUnlock();
	void writeLock();
	void writeUnlock();

	/**
	 * devuelve true si el registro ya existe en la base de datos
	 */
	bool hasRegister(std::string name);

public:

	DataBase();

	virtual ~DataBase();

	/**
	 * Carga la base de datos desde archivo
	 */
	void load();

	/**
	 * Guarda la base de datos a un archivo
	 */
	void save();

	/**
	 * Destruye el objeto DB
	 */
	void finalize();

	/**
	 * Obtiene el registro de nombre: name
	 * Devuelve null en caso de error
	 */
	const DBRegister* getRegister(std::string name);

	/**
	 * agrega un registro a la base de datos
	 * devuelve el id de registro, -1 en caso de error
	 */
	int addRegister(const DBRegister *reg);

	/**
	 * modifica un registro a la base de datos
	 * devuelve el id de registro, -1 en caso de error
	 */
	int updateRegister(const DBRegister *reg);

	/**
	 * remueve un registro a la base de datos
	 * devuelve el id de registro, -1 en caso de error
	 */
	int removeRegister(const DBRegister *reg);


};

#endif /* DATABASE_H_ */
